home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / share / hplip / base / mfpdtf.py < prev    next >
Text File  |  2008-10-13  |  18KB  |  505 lines

  1. # -*- coding: utf-8 -*-
  2. #
  3. # (c) Copyright 2003-2007 Hewlett-Packard Development Company, L.P.
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18. #
  19. # Author: Don Welch
  20. #
  21.  
  22. # Std Lib
  23. import struct
  24. import cStringIO
  25.  
  26. # Local
  27. from g import *
  28. from codes import *
  29.  
  30. # Page flags
  31. NEW_PAGE =            0x01
  32. END_PAGE  =           0x02
  33. NEW_DOCUMENT =        0x04
  34. END_DOCUMENT =        0x08
  35. END_STREAM  =         0x10
  36. RESERVED_20 =         0x20
  37. RESERVED_40 =         0x40
  38. RESERVED_80 =         0x80
  39.  
  40. MFPDTF_RASTER_BITMAP  = 0
  41. MFPDTF_RASTER_GRAYMAP = 1
  42. MFPDTF_RASTER_MH      = 2
  43. MFPDTF_RASTER_MR      = 3
  44. MFPDTF_RASTER_MMR     = 4
  45. MFPDTF_RASTER_RGB     = 5
  46. MFPDTF_RASTER_YCC411  = 6
  47. MFPDTF_RASTER_JPEG    = 7
  48. MFPDTF_RASTER_PCL     = 8
  49. MFPDTF_RASTER_NOT     = 9
  50.  
  51. # Data types for FH
  52. DT_UNKNOWN       = 0
  53. DT_FAX_IMAGES    = 1
  54. DT_SCANNED_IMAGES= 2
  55. DT_DIAL_STRINGS  = 3
  56. DT_DEMO_PAGES    = 4
  57. DT_SPEED_DIALS   = 5
  58. DT_FAX_LOGS      = 6
  59. DT_CFG_PARMS     = 7
  60. DT_LANG_STRS     = 8
  61. DT_JUNK_FAX_CSIDS= 9  
  62. DT_REPORT_STRS   = 10  
  63. DT_FONTS         = 11
  64. DT_TTI_BITMAP    = 12
  65. DT_COUNTERS      = 13
  66. DT_DEF_PARMS     = 14  
  67. DT_SCAN_OPTIONS  = 15
  68. DT_FW_JOB_TABLE  = 17
  69.  
  70. # Raster data record types
  71. RT_START_PAGE = 0
  72. RT_RASTER = 1
  73. RT_END_PAGE = 2
  74.  
  75. # FH
  76. FIXED_HEADER_SIZE = 8
  77.  
  78. # Variants
  79. IMAGE_VARIANT_HEADER_SIZE = 10
  80. DIAL_STRINGS_VARIANT_HEADER_SIZE = 6
  81. FAX_IMAGE_VARIANT_HEADER_SIZE = 74
  82.  
  83. # Data records
  84. SOP_RECORD_SIZE = 36
  85. RASTER_RECORD_SIZE = 4
  86. EOP_RECORD_SIZE = 12
  87. DIAL_STRING_RECORD_SIZE = 51
  88.  
  89. # Page flags 
  90. PAGE_FLAG_NEW_PAGE = 0x01
  91. PAGE_FLAG_END_PAGE = 0x02
  92. PAGE_FLAG_NEW_DOC = 0x04
  93. PAGE_FLAG_END_DOC = 0x08
  94. PAGE_FLAG_END_STREAM = 0x10
  95.  
  96. # Fax data variant header data source
  97. SRC_UNKNOWN = 0
  98. SRC_HOST = 2
  99. SRC_SCANNER = 5
  100. SRC_HOST_THEN_SCANNER = 6
  101. SRC_SCANNER_THEN_HOST = 7
  102.  
  103. # Fax data variant header TTI header control
  104. TTI_NONE = 0
  105. TTI_PREPENDED_TO_IMAGE = 1
  106. TTI_OVERLAYED_ON_IMAGE = 2
  107.  
  108. MAJOR_VER = 2
  109. MINOR_VER = 0
  110.  
  111.  
  112. def parseFixedHeader(buffer):
  113.     fmt = "<IHBB"
  114.     block_len, header_len, data_type, page_flags = struct.unpack(fmt, buffer[:8])
  115.     page_flags = page_flags & 0x1f
  116.     return block_len, header_len, data_type, page_flags
  117.  
  118. def parseImageVariantHeader(buffer, data_type):
  119.     if data_type == DT_SCANNED_IMAGES:
  120.         fmt = "<BBHHHH"
  121.         major_ver, minor_ver, src_pages, copies_per_page, zoom, jpeg_q_factor = struct.unpack(fmt, buffer[:10])
  122.         return major_ver, minor_ver, src_pages, copies_per_page, zoom, jpeg_q_factor
  123.     elif data_type == DT_FAX_IMAGES:
  124.         pass
  125.  
  126. def parseRecord(buffer):
  127.     record_type = struct.unpack("<B", buffer[0])[0]
  128.  
  129.     if record_type == RT_START_PAGE:
  130.         fmt = "<BBHHHIIIHHIII"
  131.         id, encoding, page_num, black_ppr, black_bpp, black_rpp, black_hort_dpi, black_vert_dpi, cmy_ppr, cmy_bpp, cmy_rpp, cmy_hort_dpi, cmy_vert_dpi = \
  132.             struct.unpack(fmt, buffer[:SOP_RECORD_SIZE])
  133.         assert id == record_type
  134.         return id, (encoding, page_num, black_ppr, black_bpp, black_rpp, black_hort_dpi, black_vert_dpi, cmy_ppr, cmy_bpp, cmy_rpp, cmy_hort_dpi, cmy_vert_dpi)
  135.  
  136.     elif record_type == RT_RASTER:
  137.         fmt = "<BBH"
  138.         id, unused, data_size = struct.unpack(fmt, buffer[:RASTER_RECORD_SIZE])
  139.         assert id == record_type
  140.         return id, (unused, data_size)
  141.  
  142.     elif record_type == RT_END_PAGE:
  143.         fmt = "<BBBBII"
  144.         id, unused1, unused2, unused3, black_rows, cmy_rows = struct.unpack(fmt, buffer[:EOP_RECORD_SIZE])
  145.         assert id == record_type
  146.         return id, (unused1, unused2, unused3, black_rows, cmy_rows)
  147.  
  148.     log.error("Error: Invalid record type: %d" % record_type)
  149.     raise Error(ERROR_INTERNAL)
  150.  
  151.  
  152.  
  153. def readChannelToStream(device, channel_id, stream, single_read=True, callback=None):
  154.     STATE_END, STATE_FIXED_HEADER, STATE_VARIANT_HEADER, STATE_RECORD = range(4)
  155.     state, total_bytes, block_remaining, header_remaining, data_remaining = 1, 0, 0, 0, 0
  156.     endScan = False
  157.     while state != STATE_END:
  158.         log.debug("**** State %d ****" % state)
  159.         if state == STATE_FIXED_HEADER: 
  160.  
  161.             if endScan:
  162.                 state = STATE_END
  163.                 break
  164.  
  165.             if data_remaining == 0:
  166.                 fields, data = device.readChannel(channel_id)
  167.                 data_remaining = len(data)
  168.                 if callback is not None:
  169.                     endScan = callback()
  170.  
  171.             block_len, header_len, data_type, page_flags = parseFixedHeader(data)
  172.             block_remaining, header_remaining = block_len-FIXED_HEADER_SIZE, header_len-FIXED_HEADER_SIZE
  173.             log.debug("Fixed header: (datalen=%d(0x%x),blocklen=%d(0x%x),headerlen=%d(0x%x),datatype=0x%x,pageflags=0x%x)" % 
  174.                 (len(data), len(data), block_len, block_len, header_len, header_len, data_type, page_flags))
  175.             data_remaining -= FIXED_HEADER_SIZE
  176.             data = data[FIXED_HEADER_SIZE:]
  177.             state = STATE_RECORD
  178.             log.debug("Data: data=%d,block=%d,header=%d" % (data_remaining, block_remaining, header_remaining))
  179.  
  180.             if page_flags & PAGE_FLAG_END_STREAM:
  181.                 state = STATE_END
  182.                 break
  183.  
  184.             if header_remaining > 0:
  185.                 state = STATE_VARIANT_HEADER
  186.  
  187.  
  188.         elif state == STATE_VARIANT_HEADER:
  189.             if data_type == DT_SCANNED_IMAGES:
  190.                 major_ver, minor_ver, src_pages, copies_per_page, zoom, jpeg_q_factor = parseImageVariantHeader(data, data_type)
  191.                 log.debug("Variant header: (major/minor=%d/%d,src_pages=%d,copies_per_page=%d,zoom=%d,jpeg_q_factor=%d" % 
  192.                     (major_ver, minor_ver, src_pages, copies_per_page, zoom, jpeg_q_factor))
  193.                 data = data[IMAGE_VARIANT_HEADER_SIZE:]
  194.                 block_remaining -= IMAGE_VARIANT_HEADER_SIZE
  195.                 header_remaining -= IMAGE_VARIANT_HEADER_SIZE
  196.                 data_remaining -= IMAGE_VARIANT_HEADER_SIZE
  197.  
  198.             elif data_type == DT_FAX_IMAGES:
  199.                 log.error("Unsupported data type")
  200.  
  201.             else:
  202.                 log.error("Unsupported data type")
  203.  
  204.             log.debug("Data: data=%d,block=%d,header=%d" % (data_remaining, block_remaining, header_remaining))
  205.  
  206.             if header_remaining > 0:
  207.                 log.error("Header size error.")
  208.                 state = STATE_END
  209.                 continue
  210.  
  211.             state = STATE_RECORD
  212.             if block_remaining == 0:
  213.                 state = STATE_FIXED_HEADER
  214.             continue
  215.  
  216.         elif state == STATE_RECORD:
  217.             record_type, record = parseRecord(data)
  218.  
  219.             if record_type == RT_START_PAGE:
  220.                 encoding, page_num, black_ppr, black_bpp, black_rpp, black_hort_dpi, black_vert_dpi, \
  221.                     cmy_ppr, cmy_bpp, cmy_rpp, cmy_hort_dpi, cmy_vert_dpi = record
  222.                 log.debug("Start page record: (encoding=0x%x, page=%d)" % (encoding, page_num))
  223.                 data = data[SOP_RECORD_SIZE:]
  224.                 block_remaining -= SOP_RECORD_SIZE
  225.                 data_remaining -= SOP_RECORD_SIZE
  226.                 if block_remaining != 0:
  227.                     log.error("Block size error.")
  228.                     state = STATE_END
  229.                     continue
  230.  
  231.                 if single_read:
  232.                     state = STATE_END
  233.                 else:                    
  234.                     state = STATE_FIXED_HEADER
  235.                     log.debug("Data: data=%d,block=%d,header=%d" % (data_remaining, block_remaining, header_remaining))
  236.                 continue
  237.  
  238.             elif record_type == RT_RASTER:
  239.                 unused, data_size = record
  240.                 log.debug("Raster record: (data size=%d(0x%x))" % (data_size, data_size))
  241.                 data = data[RASTER_RECORD_SIZE:]
  242.                 block_remaining -= RASTER_RECORD_SIZE
  243.                 data_remaining -= RASTER_RECORD_SIZE
  244.                 log.debug("Data: data=%d,block=%d,header=%d" % (data_remaining, block_remaining, header_remaining))
  245.  
  246.                 if block_remaining > 0 and data_remaining > 0:
  247.                     log.debug("Writing remainder of data...")
  248.                     data_len = len(data)
  249.                     log.debug("Data len=%d(0x%x)" % (data_len,data_len))
  250.                     stream.write(data[:block_remaining])
  251.                     block_remaining -= data_len
  252.                     data_remaining -= data_len
  253.  
  254.                     if data_remaining != 0:
  255.                         log.error("Data size error")
  256.                         state = STATE_END
  257.                         continue
  258.  
  259.                 while block_remaining > 0:
  260.                     if endScan:
  261.                         #state = STATE_END
  262.                         break
  263.  
  264.                     log.debug("Reading more data from device...")
  265.                     fields, data = device.readChannel(channel_id)
  266.  
  267.                     if callback is not None:
  268.                         endScan = callback()
  269.  
  270.                     data_len = len(data)
  271.                     log.debug("Data len=%d(0x%x)" % (data_len,data_len))
  272.                     stream.write(data[:block_remaining])
  273.                     total_bytes += data_len
  274.                     block_remaining -= data_len
  275.  
  276.                 if block_remaining != 0:
  277.                     log.error("Block size error.")
  278.                     state = STATE_END
  279.                     continue
  280.  
  281.                 state = STATE_FIXED_HEADER
  282.                 continue
  283.  
  284.             elif record_type == RT_END_PAGE:
  285.                 unused1, unused2, unused3, black_rows, cmy_rows = record
  286.                 log.debug("End page record: (black_rows=%d,cmy_rows=%d)" % (black_rows, cmy_rows))
  287.                 data = data[EOP_RECORD_SIZE:]
  288.                 block_remaining -= EOP_RECORD_SIZE
  289.                 data_remaining -= EOP_RECORD_SIZE
  290.                 if block_remaining != 0:
  291.                     log.error("Block size error.")
  292.                 log.debug("Data: data=%d,block=%d,header=%d" % (data_remaining, block_remaining, header_remaining))
  293.  
  294.                 if page_flags & PAGE_FLAG_END_DOC or \
  295.                    page_flags & PAGE_FLAG_END_STREAM:
  296.                     state = STATE_END
  297.                 else:
  298.                     state = STATE_FIXED_HEADER
  299.                 continue
  300.  
  301.     log.debug("Read %d bytes" % total_bytes)
  302.     return endScan 
  303.  
  304.  
  305.  
  306. def buildMFPDTFBlock(data_type, page_flags=0, send_variant=False, data=None):
  307.     # Fixed header
  308.     # [Variant header - dial, fax, or scan]
  309.     # Data Record
  310.  
  311.     block = cStringIO.StringIO()
  312.     block.write(struct.pack("<I", 0)) # Block len (4bytes)
  313.     header_len = FIXED_HEADER_SIZE
  314.  
  315.     if send_variant:
  316.         if data_type == DT_DIAL_STRINGS:
  317.             header_len += DIAL_STRINGS_VARIANT_HEADER_SIZE
  318.  
  319.         elif data_type == DT_FAX_IMAGES:
  320.             header_len += FAX_IMAGE_VARIANT_HEADER_SIZE
  321.  
  322.     block.write(struct.pack("<H", header_len)) # Header len (2 bytes)
  323.     block.write(struct.pack("<B", data_type)) # Data type (1 byte)
  324.     block.write(struct.pack("<B", page_flags)) # Page flags (1 byte)
  325.  
  326.     if send_variant:
  327.         if data_type == DT_DIAL_STRINGS:
  328.             block.write(struct.pack("<BB", MAJOR_VER, MINOR_VER))
  329.             block.write(struct.pack("<H", 1)) # num strings
  330.             block.write(struct.pack("<H", 51)) # ?
  331.  
  332.         elif data_type == DT_FAX_IMAGES:
  333.             block.write(struct.pack("<BB", MAJOR_VER, MINOR_VER))
  334.             block.write(struct.pack("<B", SRC_HOST)) # Data source (1 byte)
  335.             block.write(struct.pack("<H", 1)) # Num pages (2 bytes)
  336.             block.write(struct.pack("<B", TTI_NONE)) # TTI control
  337.             block.write(struct.pack("<I", 0)) # time (4 bytes)
  338.             block.write("\x00"*20) # T30_CSI (20 bytes)
  339.             block.write("\x20"*20) # T30_SUB (20 bytes)
  340.             block.write("\x20"*20) # T30_PWD (20 bytes)
  341.             block.write("<I", 0) # xaction ID (4 bytes)
  342.  
  343.     if data_type == DT_DIAL_STRINGS:
  344.         if data is not None:
  345.             dial_string = data['dial-string']
  346.             block.write(dial_string)
  347.             block.write('\x00'*(51-len(dial_string)))
  348.  
  349.     elif data_type == DT_FAX_IMAGES:
  350.         pass
  351.  
  352.  
  353.     # fixed header (8 bytes):
  354.     # 
  355.     # +----------------------------+
  356.     # |                            |
  357.     # | block len (32 bits)        |
  358.     # | length of entire           |
  359.     # | block of data              |
  360.     # +----------------------------+
  361.     # |                            |
  362.     # | header length (16 bits)    |
  363.     # | length of fixed and        |
  364.     # | variant header (if any)    |
  365.     # | ==8 if no variant (fixed   |
  366.     # |   only                     |
  367.     # | >8 if variant header       |
  368.     # |                            |
  369.     # +----------------------------+
  370.     # |                            | 1=FAX
  371.     # | data type (8 bits)         | 3=DIAL_STRINGS
  372.     # | data type of data record(s)| 12=TTI BITMAP
  373.     # |                            |
  374.     # +----------------------------+
  375.     # |                            |
  376.     # | page flags (8 bits)        |
  377.     # |                            |
  378.     # +----------------------------+
  379.     #
  380.     # followed by variant header and/or 
  381.     # data record(s)...
  382.     #
  383.     # image header variant (10 bytes)
  384.     # 
  385.     # +----------------------------+
  386.     # |                            |
  387.     # | major ver (8 bits)         |
  388.     # |                            |
  389.     # +----------------------------+
  390.     # |                            |
  391.     # | minor ver (8 bits)         |
  392.     # |                            |
  393.     # +----------------------------+
  394.     # |                            |
  395.     # | source pages (16 bits)     |
  396.     # |                            |
  397.     # +----------------------------+
  398.     # |                            |
  399.     # | copies/page (16 bits)      |
  400.     # |                            |
  401.     # +----------------------------+
  402.     # |                            |
  403.     # | zoom factor (16 bits)      |
  404.     # |                            |
  405.     # +----------------------------+
  406.     # |                            |
  407.     # | jpeg Q factor (16 bits)    |
  408.     # |                            |
  409.     # +----------------------------+
  410.     #
  411.     # dial strings variant header (6 bytes)
  412.     #
  413.     # +----------------------------+
  414.     # |                            |
  415.     # | major ver (8 bits)         |
  416.     # |                            |
  417.     # +----------------------------+
  418.     # |                            |
  419.     # | minor ver (8 bits)         |
  420.     # |                            |
  421.     # +----------------------------+
  422.     # |                            |
  423.     # | num strings (16 bits)      |
  424.     # |                            |
  425.     # +----------------------------+
  426.     # |                            |
  427.     # | dial string len (16 bits)  |
  428.     # |                            |
  429.     # +----------------------------+
  430.     #
  431.     # dial string data part
  432.     # +----------------------------+
  433.     # |                            |
  434.     # | dial string (51 bytes)     |
  435.     # |                            |
  436.     # +----------------------------+
  437.     #
  438.     # start page (SOP) record (36 bytes)
  439.     # 
  440.     # +----------------------------+
  441.     # |                            |
  442.     # | id = 0 (8 bits)            |
  443.     # |                            |
  444.     # +----------------------------+
  445.     # |                            |
  446.     # | encoding (8 bits)          |
  447.     # |                            |
  448.     # +----------------------------+
  449.     # |                            |
  450.     # | page num (16 bits)         |
  451.     # |                            |
  452.     # +----------------------------+
  453.     # |                            |
  454.     # | black data desc (16 bytes) |
  455.     # |                            |
  456.     # +----------------------------+
  457.     # |                            |
  458.     # | cmy data desc (16 bytes)   |
  459.     # |                            |
  460.     # +----------------------------+
  461.     #
  462.     #
  463.     # raster data record (4 bytes + data)
  464.     # 
  465.     # +----------------------------+
  466.     # |                            |
  467.     # | id = 1 (8 bits)            |
  468.     # |                            |
  469.     # +----------------------------+
  470.     # |                            |
  471.     # | unused (8 bits)            |
  472.     # |                            |
  473.     # +----------------------------+
  474.     # |                            |
  475.     # | data bytes (n) (16 bits)   |
  476.     # |                            |
  477.     # +----------------------------+
  478.     # |                            |
  479.     # | data (n bytes)             |
  480.     # |                            |
  481.     # +----------------------------+
  482.     #
  483.     #
  484.     # end page (EOP) record (12 bytes)
  485.     # 
  486.     # +----------------------------+
  487.     # |                            |
  488.     # | id = 2 (8 bits)            |
  489.     # |                            |
  490.     # +----------------------------+
  491.     # |                            |
  492.     # | unused (24 bits)           |
  493.     # |                            |
  494.     # +----------------------------+
  495.     # |                            |
  496.     # | rows of black (32 bits)    |
  497.     # |                            |
  498.     # +----------------------------+
  499.     # |                            |
  500.     # | rows of cmy (32 bits)      |
  501.     # |                            |
  502.     # +----------------------------+
  503.     #    
  504.  
  505.